package ru.agiledev.aos.core;

import ru.agiledev.aos.commons.dto.LightWord;
import ru.agiledev.aos.commons.dto.SearchEntry;

import java.util.*;

/**
 * Created by a.kirillov
 * Date: 2/14/12 Time: 10:03 PM
 */
public class ResultsRanker {
    public ResultsRanker() {
    }
    //todo: в будущем проработать разные сценарии ранжирования
    public List<SearchEntry> rankQueries(List<LightWord> firstObject, List<SearchEntry> entries){
        HashMap<String, SearchEntry> res = new HashMap<String, SearchEntry>(entries.size());

        for(SearchEntry entry:entries){
            if(isSnippetAppropriate(entry, firstObject)){
                if(!res.containsKey(entry.getDomain())){
                    entry.setAosRank(1);
                    res.put(entry.getDomain(), entry);
                } else {
                    res.get(entry.getDomain()).increaseRank(1);
                }
            }
        }

        List<SearchEntry> resultSet = new ArrayList<SearchEntry>(res.values());

        Collections.sort(resultSet, new Comparator<SearchEntry>() {
            @Override
            public int compare(SearchEntry o1, SearchEntry o2) {
                int comp = o2.getAosRank() - o1.getAosRank();
                return comp;
            }
        });

        if(resultSet.size()>19){
            return resultSet.subList(0,20);
        } else {
            return resultSet;
        }
    }

    private boolean isSnippetAppropriate(SearchEntry entry, List<LightWord> firstObject){
        for(int i = firstObject.size()-1; i>=0; i--){
            LightWord word = firstObject.get(i);

            if(entry.getTitle().toLowerCase().contains(word.getValue())||entry.getText().toLowerCase().contains(word.getValue())){
                return true;
            }

            HashSet<String> stems = word.getStems();
            for (Iterator<String> iterator = stems.iterator(); iterator.hasNext();) {
                String stem = iterator.next();
                if(entry.getTitle().toLowerCase().contains(stem)||entry.getText().toLowerCase().contains(stem)){
                    return true;
                }
            }
        }
        return false;
    }
}
